//命令式编程：原生js开发或者jquery通过命令操作DOM对象完成数据更改，界面变化
//声明式编程：框架底层已经封装号模块帮助完成DOM操作，只需声明即可使用vue react angular{{}}
//编程范式：命令式编程和声明式编程
//编程范式：面向对象的编程与面向过程的编程
//面向过程方式：他的第一个公民是函数，他围绕着函数进行编程，也就是函数式编程

const nums = [11,20,33,444,50,40]

//1. 从nums 数组中取出小于100的数

let newNums = []
for (const n of nums) {
    if (n < 100){
        newNums.push(n)
    }
}
console.log(newNums);

// 2. 从（1）要求中小于100的数都乘以2
let newNewNums = []
for (const n of newNums) {
    newNewNums.push(n * 2)
}
console.log(newNewNums);

//3、从（2）要求中 把所有数进行累加，得到最终结果
let total = 0
for (const n of newNewNums) {
    total += n
}
console.log(total);
//通过js逻辑操作完成需求

//---函数式编程---

//封装了一些函数用来实现一些效果
// 1）filter函数的使用
// 参数是一个回调函数，数组有多少个成员，就回调多少次
let newNums1 = nums.filter(function(n){  //此回调函数编写过滤规则
    // 匿名函数中，有一个参数n，是每一次回调的数组成员，第一次n就为10，第二次就为第二个成员20
    // 匿名函数必须返回的是布尔值，true返回n进入到新的数组中
    return n < 100
})
console.log(newNums1);

// 2) map函数的使用
// 它可以对数组中每个内容进行操作
// 参数也为一个匿名回调函数
let newNewNums1 = newNums1.map(function (n) {
    // 参数n指代每次回调的数组成员
    return n * 2
})
console.log(newNewNums1);

// 3) reduce函数，第一个参数为匿名回调函数，第二个参数为默认值
// 作用就对数组中所有内容进行汇总

let total1 = newNewNums1.reduce(function(preValue,n){
    // 匿名回调函数中，第一个参数preValue 指代上一次返回的值
    // 第二个参数为n，本次回调进入的数组成员
    return preValue + n
},0)//默认值为0
console.log(total1)

//把三个需求进行综合，一起提出
let totalnums = nums.filter(function(n){
    return n < 100
}).map(function(n){
    return n * 2
}).reduce(function(preValue,n){
    return preValue + n
},0)
console.log(totalnums);
//链式编程：把多个函数串起来，把结果作为下一个函数的参数

// 简写
// 箭头函数参数只有一个，可以删除括号
// 当箭头函数 函数体 代码只有一行 是return代码，可以省略大括号和return
let totalnums2 = nums.filter(n => n < 100).map(n => n * 2).reduce((preValue,n)=> preValue + n,0)
console.log(totalnums2);